﻿using Leeder.Model.Handler;
using Leeder.Plugin;
using PickingGuide.Enum;
using PickingGuide.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PickingGuide.Handle
{
    /// <summary>
    /// IO卡
    /// </summary>
    public class IOCardHelper
    {
        private IOCardHandler iOCardHandler;

        /// <summary>
        /// 消息通知事件
        /// </summary>
        public event Action<string, MessageType> MesgEvent;
        public event Action<List<IOCardSignalModel>> OnInputSignalChanged;

        /// <summary>
        /// IO卡状态
        /// </summary>
        public bool IoCardStatus { get; set; }

        private const string CloseAllCMD = "001";
        private const string ResetCMD = "002";
        private const string AwaitCMD = "003";
        private const string AlarmCMD = "004";
        private const string CompleteCMD = "005";
        private const string PokayokeJudgeCMD = "008";
        private const string PokayokeStartCMD = "010";
        private const string PokayokeOkCMD = "012";

        /// <summary>
        /// IO卡初始化
        /// </summary>
        /// <param name="iOCardHandler">IO卡对象</param>
        /// <param name="ioConfigs">IO卡指令配置</param>
        /// <param name="comm">IO卡COM口</param>
        /// <returns></returns>
        public bool InitIOCard(List<IoCarConfigModel> ioConfigs, string comm)
        {
            try
            {
                //IO卡连接和初始化
                iOCardHandler = new IOCardHandler(comm);
                var AllIOCommand = ioConfigs.Select(x => new IOCardCMDModel
                {
                    ID = x.ID,//主键
                    Code = x.Code,//指令代码
                    Desc = x.Description,//描述
                    InSignal = x.InSignal,//指令对应的入口
                    InState = x.InState,//指令对应的入口状态
                    OutSignal = x.OutSignal,//指令对应的出口
                    OutState = x.OutState,//指令对应的入口状态
                    InHoldTime = x.InHoldTime,//输入持续时间
                    InHTSuccessCommandID = x.InHTSuccessCommandID,//输入持续时间成功后下一步操作（对应主键）
                    InHTFailCommandID = x.InHTFailCommandID,//输入持续时间即使失败也下一步的操作（对应主键）
                    OutHoldTime = x.OutHoldTime,//输出持续时间
                    AfterOutHTCommandID = x.AfterOutHTCommandID//输出时间结束后执行的操作
                }).ToList();
                iOCardHandler.LoadCommand(AllIOCommand);
                iOCardHandler.OnConnectionBreak += IoCarConnectionEvent;
                //iOCardHandler.OnIOCarConnectionBreak += IoCarConnectionEvent;
                iOCardHandler.OnOutSignalFail += IOCardHandler_OnOutSignalFail;
                iOCardHandler.OnInputSignalChanged += OnInputSignalChang;
                iOCardHandler.IsInitiativeRequest = true;
                iOCardHandler.Start();
                IoCardStatus = true;
                return true;
            }
            catch (Exception ex)
            {
                iOCardHandler = default;
                MesgEvent?.BeginInvoke("IO卡初始化失败！" + ex.Message, MessageType.Error, null, null);
                return false;
            }
        }

        /// <summary>
        /// IO卡指令执行错误事件
        /// </summary>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        private void IOCardHandler_OnOutSignalFail(int arg1, bool arg2)
        {
            MesgEvent?.BeginInvoke("IO卡指令执行错误，错误端口:" + arg1 + "，错误状态:" + arg2, MessageType.Error, null, null);
        }

        /// <summary>
        /// IO卡连接状态变化事件
        /// </summary>
        /// <param name="str"></param>
        private void IoCarConnectionEvent(string str)
        {
            MesgEvent?.BeginInvoke("IO卡连接状态变化:" + str, MessageType.Info, null, null);
        }

        /// <summary>
        /// IO卡连接状态变化事件
        /// </summary>
        private void IoCarConnectionEvent()
        {
            MesgEvent?.BeginInvoke("IO卡连接状态变化", MessageType.Info, null, null);
        }

        /// <summary>
        /// IO卡输入端口状态实时监控及逻辑处理
        /// </summary>
        /// <param name="list">输入端口集合</param>
        public void OnInputSignalChang(List<IOCardSignalModel> list)
        {
            OnInputSignalChanged?.BeginInvoke(list, null, null);
        }

        /// <summary>
        /// IO卡输出(初始化)
        /// </summary>
        public void IoCardInitAction()
        {
            MesgEvent?.BeginInvoke("IO卡输出(初始化)", MessageType.Info, null, null);
            if (IoCardStatus)
                try { iOCardHandler.WriteOutput(ResetCMD); } catch (Exception ex) { }
        }

        /// <summary>
        /// IO卡输出(错误)
        /// </summary>
        public void IoCardErrorAction()
        {
            MesgEvent?.BeginInvoke("IO卡输出(错误)", MessageType.Info, null, null);
            if (IoCardStatus)
                try { iOCardHandler.WriteOutput(AlarmCMD); } catch (Exception ex) { }
        }

        /// <summary>
        /// IO卡输出(完成)
        /// </summary>
        public void IoCardCompleteAction()
        {
            MesgEvent?.BeginInvoke("IO卡输出(完成)", MessageType.Info, null, null);
            if (IoCardStatus)
                try { iOCardHandler.WriteOutput(CompleteCMD); } catch (Exception ex) { }
        }

        /// <summary>
        /// IO卡输出(判定)
        /// </summary>
        public void IoCardJudgeAction()
        {
            MesgEvent?.BeginInvoke("IO卡输出(判定)", MessageType.Info, null, null);
            if (IoCardStatus)
                try { iOCardHandler.WriteOutput(PokayokeJudgeCMD); } catch (Exception ex) { }
        }

        /// <summary>
        /// IO卡输出(开始)
        /// </summary>
        public void IoCardStartAction()
        {
            MesgEvent?.BeginInvoke("IO卡输出(开始)", MessageType.Info, null, null);
            if (IoCardStatus)
                try { iOCardHandler.WriteOutput(PokayokeStartCMD); } catch (Exception ex) { }
        }

        /// <summary>
        /// IO卡输出(OK)
        /// </summary>
        public void IoCardOkAction()
        {
            MesgEvent?.BeginInvoke("IO卡输出(OK)", MessageType.Info, null, null);
            if (IoCardStatus)
                try { iOCardHandler.WriteOutput(PokayokeOkCMD); } catch (Exception ex) { }
        }

        /// <summary>
        /// IO卡输出(作业中)
        /// </summary>
        public void IoCardAwaitAction()
        {
            MesgEvent?.BeginInvoke("IO卡输出(作业中)", MessageType.Info, null, null);
            if (IoCardStatus)
                try { iOCardHandler.WriteOutput(AwaitCMD); } catch (Exception ex) { }
        }

        /// <summary>
        /// IO卡输出(重置)
        /// </summary>
        public void IoCardResetAction()
        {
            MesgEvent?.BeginInvoke("IO卡输出(重置)", MessageType.Info, null, null);
            if (IoCardStatus)
                try { iOCardHandler.WriteOutput(ResetCMD); } catch (Exception ex) { }
        }

        /// <summary>
        /// IO卡输出(关闭)
        /// </summary>
        public void IoCardCloseAction()
        {
            MesgEvent?.BeginInvoke("IO卡输出(关闭)", MessageType.Info, null, null);
            if (IoCardStatus)
                try { iOCardHandler.WriteAllOutput(false); } catch (Exception ex) { }
        }

        /// <summary>
        /// IO卡输出
        /// </summary>
        public void IoCardAction(string code)
        {
            MesgEvent?.BeginInvoke($"IO卡输出指令{code}", MessageType.Info, null, null);
            if (IoCardStatus)
                try { iOCardHandler.WriteOutput(code); } catch (Exception ex) { }
        }
    }
}
